import subprocess
import os
import time

import pyautogui
import win32gui
import pickle
import argparse
import win32con
import pygetwindow as gw


def get_args():
    parser = argparse.ArgumentParser()
    parser.add_argument("--git_name", type=str, help="统计代码行数是根据git log统计的，需要你的git内的name")
    parser.add_argument("--git_window_title_key", type=str, default="MINGW64", help="git标题关键词，用来查找git窗口的")
    return parser.parse_args()


args = get_args()


def get_all_window_hwnds():
    """Return all window handles."""
    hwnds = []

    def callback(hwnd, data):
        hwnds.append(hwnd)

    win32gui.EnumWindows(callback, None)
    return set(hwnds)


# 找git窗口句柄
def get_git_handle(git_location_path):
    retry = 0
    while True:
        if retry > 10:
            break
        retry += 1
        time.sleep(1)
        subprocess.Popen([git_location_path])
        time.sleep(2)
        hwnds_after = get_all_window_hwnds()
        git_handles = []
        for window in hwnds_after:
            if args.git_window_title_key in win32gui.GetWindowText(window):
                git_handles.append(window)
        if len(git_handles)>1:
            for window in git_handles:
                win32gui.PostMessage(window, win32con.WM_CLOSE, 0, 0)
        elif len(git_handles)==1:
            return git_handles[0]


# 找git安装目录
def find_git_bash_path():
    try:
        # 执行where git命令
        result = subprocess.check_output('where git', shell=True, text=True).strip()

        # 获取git的安装目录
        git_directory = os.path.dirname(result)

        # 获取上级目录
        parent_directory = os.path.dirname(git_directory)

        # 构建git-bash的路径
        git_bash_path = os.path.join(parent_directory, "git-bash.exe")

        if os.path.exists(git_bash_path):
            return git_bash_path
        else:
            return None
    except subprocess.CalledProcessError:
        # 如果'where git'没有找到结果，则返回None
        return None


git_bash_location = find_git_bash_path()
if git_bash_location:
    print(f"git-bash.exe is located at: {git_bash_location}")
else:
    print("Could not find git-bash.exe")

# 读取repository_url，首先克隆所有的库下来
with open("repository_urls.pkl", "rb") as fp:
    urls = pickle.load(fp)

repo_dict = {}
for url in urls:
    url = url.replace("https://", "")
    u_split = ["https:/"] + url.split("/")
    repo_url = "/".join(u_split[:-2])
    branch = u_split[-1]
    if repo_url not in repo_dict:
        repo_dict[repo_url] = set()
    repo_dict[repo_url].add(branch)

print("所有仓库为与分支为:")
print(repo_dict)

# 克隆所有仓库
for repo in repo_dict:
    repo_dir = repo.split("/")[-1]
    print(f"正在克隆{repo}。大仓库可能要克隆较久时间，耐心等待即可。")
    cmd = f"""cd result && mkdir {repo_dir} && cd {repo_dir} && git clone {repo}"""
    result = subprocess.run(['cmd', '/c', cmd], capture_output=True, text=True)
    print(result.stdout)
    print(result.stderr)
    print(f"{repo}克隆成功")

# 切换对应分支，截图，收工
line_statistic_cmd = f"""git log --author={args.git_name} """
line_statistic_cmd += """--pretty=tformat: --numstat | awk '{ add += $1; subs += $2; loc += $1 - $2 } END { printf "add lines: %s, sub: %s, total: %s", add, subs, loc }'"""
for repo in repo_dict:
    for branch in repo_dict[repo]:
        repo_dir = repo.split("/")[-1]
        print(f"正在切换到{repo}的{branch}分支")
        cmd = f"""cd result\\{repo_dir}\\{repo_dir} && git checkout {branch} --force"""
        result = subprocess.run(['cmd', '/c', cmd], capture_output=True, text=True)
        print(result.stdout)
        print(result.stderr)
        print(f"{repo}分支{branch}切换成功")
        # 创建git窗口
        time.sleep(1)
        git_handle = get_git_handle(git_bash_location)
        print(git_handle)
        time.sleep(0.5)
        # 确定窗口位置
        rect = win32gui.GetWindowRect(git_handle)
        x, y, x1, y1 = rect
        print(rect)
        # 使窗口获得焦点
        title = win32gui.GetWindowText(git_handle)
        print(title)
        while gw.getWindowsWithTitle(title) is None:
            time.sleep(0.5)
        gw.getWindowsWithTitle(title)[0].activate()
        # 输入指令
        time.sleep(0.5)
        pyautogui.write(f"cd result/{repo_dir} && cd $(ls -d */)")
        pyautogui.press("enter")
        time.sleep(3)
        pyautogui.write(line_statistic_cmd)
        pyautogui.press("enter")
        time.sleep(3)
        # 截图
        screenshot = pyautogui.screenshot(region=(x, y, x1 - x, y1 - y))
        img_name = f"result/{repo_dir}_{branch}.png"
        screenshot.save(img_name)
        win32gui.PostMessage(git_handle, win32con.WM_CLOSE, 0, 0)
        time.sleep(0.5)
